
#include "CBondFilter.h"
#include "CBondSource.h"
#include "../BondContainer.h"
#include "uam/UserAccountManager.h"
#include "../SSVContainer.h"
#include "../CompanyReport.h"
#include "../SSCFETSQuote.h"

CBondBankRep* CBondFilter::GetBankRep(int nIndex)
{
	return CBondContainer::instance().GetBankRep(nIndex);
}

CBondBankRep* CBondFilter::GetClntRep(int nIndex)
{
	return CBondContainer::instance().GetClntRep(nIndex);
}

CBondCompanyRep* CBondFilter::GetCompanyRep(int nIndex)
{
	return CBondContainer::instance().GetCompanyRep(nIndex);
}

CCFETSQuoteRep* CBondFilter::GetCFETSRep(int nIndex)
{
	return CBondContainer::instance().GetCFETSQuote(nIndex);
}

int CBondFilter::GetAllBondsSize()
{
	return CBondContainer::instance().GetSize();
}

CBondFilter::CBondFilter() :m_use_condition(true), bAll(false), m_condition(0), m_checkbonds(false)
{

}

void CBondFilter::SetCondition(BLHCONDITION* blh, bool bAll)
{
	if(blh)
	{
		m_use_condition = true;
		m_condition_temp = *blh;
		m_condition = &m_condition_temp;
		this->bAll = bAll;
	}else
	{
		m_condition = 0;
		m_use_condition = false;
	}
}

BLHCONDITION* CBondFilter::GetCondition()
{
	return m_condition;
}

void CBondFilter::SetBrokers(const std::list<std::string>& brokers)
{
	m_brokls.clear();
	m_brokls.assign(brokers.begin(),brokers.end());
}
bool CBondFilter::ProcessBond(int nTmpKey, IBrokerKeyDest* dest, void* context)
{
	if (nTmpKey < 0 || nTmpKey >= GetAllBondsSize()) return false;

	int added = 0;
	if (!m_use_condition)
	{
		std::list<std::string> ::const_iterator itrbrk = m_brokls.begin();
		for (; itrbrk != m_brokls.end(); itrbrk++)
		{
			added++;
			dest->OnBrokerKeyFound(nTmpKey, itrbrk->c_str(), context);
		}
		return added > 0;
	}

	BLHCONDITION& condStr = *m_condition;
	char szkey[10] = { 0 };
	bool isAllin = condStr.IsPriceNeedShowFastCheck();//无需检查是否是有效报价,提升速度
	if (isAllin)
	{
		if (bAll)
		{
			int nSize = sizeof(condStr.nBrokId) / sizeof(UINT);
			for (int i = 0; i < nSize; i++)
			{
				if (condStr.nBrokId[i] == 0x00)	break;
				memset(szkey, 0, sizeof(szkey));
				FMTBUF(szkey,"%d", condStr.nBrokId[i]);
				dest->OnBrokerKeyFound(nTmpKey, szkey, context);
			}
		}
		else
		{
			dest->OnBrokerKeyFound(nTmpKey, condStr.sCompanyid, context);
		}
		return true;
	}

	// 有效报价
	class BrokerCollector : public CBondCompanyRep::ApplyCallback{
		const BLHCONDITION&	m_cond;
		int					m_index;
		IBrokerKeyDest*		m_dest;
		void*				m_context;
		int					m_added;
		bool				m_all;
	public:
		BrokerCollector(const BLHCONDITION & condStr, int index, IBrokerKeyDest* dest, void* context,bool all) :
			m_dest(dest), m_context(context), m_cond(condStr), m_index(index), m_added(0), m_all(all){}
		int GetAdded()const{ return m_added; }
		virtual bool DoAccess(const REPORT& rept)
		{
			if (m_all)
			{
				int nCorpID = atoi(rept.m_company_id);
				if (!CBrokerList::IsValidBroker(nCorpID))
					return true;//过滤非Broker
			}
			if (CSSVContainer::IsPriceNeedShow(m_cond, rept, m_index))
			{
				m_added++;
				m_dest->OnBrokerKeyFound(m_index, rept.m_company_id, m_context);
			}
			return true;
		}
	};

	{//经纪商
		CBondCompanyRep* ptmp = GetCompanyRep(nTmpKey);
		if (ptmp && ptmp->GetSize() > 0)
		{
			BrokerCollector collector(condStr, nTmpKey, dest, context,bAll);
			ptmp->ApplyAccess(bAll, condStr.sCompanyid, &collector);
			added += collector.GetAdded();
		}
	}
	return added > 0;
}

bool CBondFilter::ProcessBondCFETS(int nType, int nTmpKey, IBrokerKeyDest* dest, void* context)
{
	if (!CBondContainer::instance().IsValidIndex(nTmpKey))return false;

	if (!m_use_condition)
	{
		static char sBroker[33] = { 0 };
		FMTBUF(sBroker, "%d", nType);
		dest->OnBrokerKeyFound(nTmpKey, sBroker, context);
		return true;
	}
	if (m_condition && m_condition->nCFETSQuoteType > CCFETSQuote::QINVALID && m_condition->nCFETSQuoteType < CCFETSQuote::QMAX)
	{
		char sType[16] = { 0 };
		FMTBUF(sType, "%d", nType);
		dest->OnBrokerKeyFound(nTmpKey, sType, context);
		return true;
	}
	return false;
}

bool CBondFilter::ProcessBondCFETSDeal(int nTmpKey, IBrokerKeyDest* dest, void* context)
{
	if (nTmpKey < 0 || nTmpKey >= GetAllBondsSize())
		return false;

	if (!m_use_condition)
	{
		std::list<std::string> ::const_iterator itrbrk = m_brokls.begin();
		bool ret = false;
		for (; itrbrk != m_brokls.end(); itrbrk++)
		{
			dest->OnBrokerKeyFound(nTmpKey, itrbrk->c_str(), context);
			ret = true;
		}
		return ret;
	}

	dest->OnBrokerKeyFound(nTmpKey, "1", context);
	return true;
}

bool CBondFilter::ProcessBondSSEFI(int nTmpKey, IBrokerKeyDest* dest, void* context)
{
	int added = 0;
	if (nTmpKey < 0 || nTmpKey >= GetAllBondsSize())
		return added>0;

	if (!m_use_condition)
	{
		std::list<std::string> ::const_iterator itrbrk = m_brokls.begin();
		for (; itrbrk != m_brokls.end(); itrbrk++)
		{
			added++;
			dest->OnBrokerKeyFound(nTmpKey, itrbrk->c_str(), context);
		}
		return added > 0;
	}

	BLHCONDITION& condStr = *m_condition;
	char szkey[10] = { 0 };
	// see CSSVContainer::SetContent;
	if (condStr.nHasFlg == 0)
	{//所有报价
		if (bAll)
		{//所有经纪商
			int nSize = sizeof(condStr.nBrokId) / sizeof(UINT);
			for (int i = 0; i < nSize; i++)
			{
				if (condStr.nBrokId[i] == 0x00)
					break;
				// 先快速检查看几个控件对应的过滤器值是否全部为空,可以避免GetCompanyInfoById的开销
				bool szkey_ok = false;
				bool need_show = condStr.IsPriceNeedShowFastCheck();
				if (!need_show)
				{
					szkey_ok = true;
					memset(szkey, 0, sizeof(szkey));
					FMTBUF(szkey, "%d", condStr.nBrokId[i]);
					REPORT rpt = { 0 };
					if (CBondContainer::instance().GetCompanyInfoById(szkey, nTmpKey, rpt))
					{
						if (CSSVContainer::IsPriceNeedShow(condStr, rpt, nTmpKey, false))//无需检查是否是有效报价,提升速度
						{
							need_show = true;
						}
					}
				}
				if (need_show)
				{
					if (!szkey_ok)
					{
						memset(szkey, 0, sizeof(szkey));
						FMTBUF(szkey, "%d", condStr.nBrokId[i]);
					}
					added++;
					dest->OnBrokerKeyFound(nTmpKey, szkey, context);
				}
			}
		}
		else
		{//单个经纪商
			added++;
			dest->OnBrokerKeyFound(nTmpKey, condStr.sCompanyid, context);
		}
		return added > 0;
	}

	// 有效报价
	class BrokerCollector : public CBondCompanyRep::ApplyCallback{
		const BLHCONDITION&	m_cond;
		int					m_index;
		IBrokerKeyDest*		m_dest;
		void*				m_context;
		int					m_added;
		bool				m_all;
	public:
		BrokerCollector(const BLHCONDITION & condStr, int index, IBrokerKeyDest* dest, void* context, bool all) :
			m_dest(dest), m_context(context), m_cond(condStr), m_index(index), m_added(0), m_all(all){}
		int GetAdded()const{ return m_added; }
		virtual bool DoAccess(const REPORT& rept)
		{
			if (m_all)
			{
				int nCorpID = atoi(rept.m_company_id);
				if (!CBrokerList::IsValidBroker(nCorpID))
					return true;//过滤非Broker
			}
			if (CSSVContainer::IsPriceNeedShow(m_cond, rept, m_index))
			{
				m_added++;
				m_dest->OnBrokerKeyFound(m_index, rept.m_company_id, m_context);
			}
			return true;
		}
	};

	{//经纪商
		CBondCompanyRep* ptmp = GetCompanyRep(nTmpKey);
		if (ptmp && ptmp->GetSize() > 0)
		{
			BrokerCollector collector(condStr, nTmpKey, dest, context, bAll);
			ptmp->ApplyAccess(bAll, condStr.sCompanyid, &collector);
			added += collector.GetAdded();
		}
	}

	return added > 0;
}

void CBondFilter::BeforeReloads()
{
	if (m_checkbonds)
	{

	}
}
void CBondFilter::AfterReloads()
{

}
void CBondFilter::CheckBonds(int bid)
{
	if (m_checkbonds)
	{
		map<int, CBondInfo>::iterator it = m_listedbonds.find(bid);
		if (it == m_listedbonds.end())
			return;
		CBondInfo& bi = it->second;
		const char * key=bi.GetBondKey();
	}
}